/**
 * 文件名    ： ReloadConfig.java
 * 版权       : XX科技有限公司。
 * 描述       : <描述>
 * 修改时间：2018年11月11日
 * 修改内容：<修改内容>
 */
package com.example.demo.application.myredis;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.example.demo.application.common.encrypt.AES;
import com.example.demo.application.common.encrypt.EncryptConfig;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * <一句话功能简述> <功能详细描述>
 * 
 * @author 87431
 * @version [版本号，2019年2月16日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Component  
public class ReloadConfig {

	protected static final Logger log = LoggerFactory.getLogger(ReloadConfig.class);

	private static JedisPoolConfig jedisconfig = null;
	
	/** 是否 初始化 */
	public static boolean isnoInit = true;

	/** 是否 是 cluster集群 */
	public static boolean isUseCluster;
	/** 默认失效时间 */
	public static int defalutExpire;

	/** cluster集群 信息 */
	public static String hostAndPortCluster;

	/** 密码 */
	public static String auth;

	/** redis 节点信息 */
	public static String hostAndPortSingle;

	/**
	 * <功能> 初始化 <详细描述> redis 配置 初始化
	 * 
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static synchronized void init() {
		try {
			BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(EncryptConfig.redisConfigFilePath));
			ResourceBundle bundle  = new PropertyResourceBundle(inputStream);
			isUseCluster = Boolean.valueOf(bundle.getString("redis.is.cluster").trim());
			auth = bundle.getString("redis.pool.auth").trim();
			//解密：
			try {
				auth =AES.decrypt(auth, EncryptConfig.rootKey);
			} catch (Exception e) {
				log.error(" redis AES.decrypt ERR !");
				throw new IllegalArgumentException(" redis AES.decrypt ERR !");
			}
			hostAndPortCluster = bundle.getString("redis.cluster.nodes").trim();
			hostAndPortSingle = bundle.getString("redis.ip").trim() + ":" + bundle.getString("redis.port").trim();
			defalutExpire = Integer.valueOf(bundle.getString("redis.expire").trim());
			
			jedisconfig = new JedisPoolConfig();
			jedisconfig.setMaxTotal(Integer.valueOf(bundle.getString("redis.pool.maxActive").trim()));
			jedisconfig.setMaxIdle(Integer.valueOf(bundle.getString("redis.pool.maxIdle").trim()));
			jedisconfig.setMinIdle(Integer.valueOf(bundle.getString("redis.pool.minIdle").trim()));
			jedisconfig.setMaxWaitMillis(Long.valueOf(bundle.getString("redis.pool.maxWait").trim()));
			
			jedisconfig.setTestOnBorrow(Boolean.valueOf(bundle.getString("redis.pool.testOnBorrow").trim()));
			jedisconfig.setTestOnReturn(Boolean.valueOf(bundle.getString("redis.pool.testOnReturn").trim()));
			inputStream.close();
			isnoInit = false;
		} catch (Exception e1) {
			log.error(" redis init : ", e1);
		}
	}

	/**
	 * <功能> 初始化 <详细描述> redis cluster 客戶端初始化
	 * 
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static synchronized JedisCluster getCluster() {
		if (null == jedisconfig) {
			init();
		}
		// 主从redis连接 配置。
		String[] hostAndPorts = hostAndPortCluster.split(",");
		Set<HostAndPort> hostAndPortSet = new HashSet<HostAndPort>();
		for (String hap : hostAndPorts) {
			String ip = hap.split(":")[0];
			int port = Integer.parseInt(hap.split(":")[1]);
			HostAndPort hostAndPort = new HostAndPort(ip, port);
			hostAndPortSet.add(hostAndPort);
		}
		// 单位毫秒 connectionTimeout 300, soTimeout 500, maxAttempts 2;
		return new JedisCluster(hostAndPortSet, 3000, 5000, 2, auth, jedisconfig);// 需要密码连接的创建对象方式
	}

	/**
	 * <功能> 初始化 <详细描述> redis 客戶端初始化
	 * 
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static synchronized JedisPool getJedisPool() {
		if (null == jedisconfig) {
			init();
		}
		// 主从redis连接 配置。 单位毫秒
		String[] ipAndPort = hostAndPortSingle.split(":");
		JedisPool jedispool = new JedisPool(jedisconfig, ipAndPort[0], Integer.valueOf(ipAndPort[1]), 10000, auth);
		return jedispool;
	}

	public static synchronized void reload() {
		jedisconfig = null;
	}
}
